import gradio as gr
import numpy as np
import hyperlpr3 as lpr3
from PIL import Image, ImageDraw, ImageFont
import cv2


def recognize_license_plate(image):
    try:
        # 将 PIL.Image 转换为 NumPy 数组并转换为 BGR 格式
        image_array = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)

        # 实例化识别对象
        catcher = lpr3.LicensePlateCatcher(detect_level=lpr3.DETECT_LEVEL_HIGH)

        # 识别车牌
        results = catcher(image_array)

        print(f"识别到 {len(results)} 个车牌")
        print(f"results: {results}")

        if len(results) == 0:
            return image, "未识别到任何车牌"

        plate_numbers = []

        for result in results:
            print(f"处理结果: {result}")

            if len(result) == 4:
                code, confidence, _, bbox = result
                print(f"识别结果: {code}, 置信度: {confidence}, bbox: {bbox}")

                plate_numbers.append(f"{code} - {confidence:.2f}")

                if isinstance(bbox, list) and len(bbox) == 4:
                    # 处理 bbox 数据
                    x1, y1, x2, y2 = bbox
                    points = [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]
                    print(f"转换后的点: {points}")

                    # 使用 OpenCV 绘制多边形
                    pts = np.array(points, np.int32)
                    pts = pts.reshape((-1, 1, 2))
                    cv2.polylines(image_array, [pts], isClosed=True, color=(0, 0, 255), thickness=2)

                    # 将中文车牌号码通过 PIL 绘制到图像上
                    result_image_pil = Image.fromarray(cv2.cvtColor(image_array, cv2.COLOR_BGR2RGB))
                    draw = ImageDraw.Draw(result_image_pil)

                    # 选用字体（请根据系统安装字体情况调整路径）
                    # Windows 示例字体路径: C:\Windows\Fonts\simhei.ttf
                    # Linux 示例字体路径: /usr/share/fonts/truetype/freefont/FreeMono.ttf
                    try:
                        font_path = "D:/字体/platech.ttf"
                        font = ImageFont.truetype(font_path, 36)
                    except IOError:
                        font = ImageFont.load_default()

                    # 获取文本大小
                    min_y = min(point[1] for point in points)
                    text_bbox = draw.textbbox((points[0][0], min_y - 36), code, font=font)

                    # 在车牌上方写上识别出的车牌号码，带背景
                    draw.rectangle(text_bbox, fill="white")
                    draw.text((points[0][0], min_y - 36), code, fill=(0, 0, 255), font=font)

                    # 将图像转换回 NumPy 数组
                    image_array = cv2.cvtColor(np.array(result_image_pil), cv2.COLOR_RGB2BGR)
                else:
                    print(f"bbox 格式不正确或为非预期列表，bbox: {bbox}")
            else:
                print(f"结果格式不正确，result: {result}")

        # 将图像从 BGR 转回 RGB 格式
        result_image = cv2.cvtColor(image_array, cv2.COLOR_BGR2RGB)
        result_image_pil = Image.fromarray(result_image)

        return result_image_pil, '\n'.join(plate_numbers)
    except Exception as e:
        print("错误信息:", str(e))
        return image, "识别过程中发生错误: " + str(e)


iface = gr.Interface(
    fn=recognize_license_plate,
    inputs=gr.Image(type='pil'),
    outputs=[gr.Image(type='pil'), gr.Textbox()],
    title='车牌识别',
    description='选择一张包含车牌的图片, 点击"识别"按钮进行车牌识别。',
    examples=[
        ['examples/example1.jpg'],
        ['examples/example2.jpg'],
        ['examples/example3.jpg']
    ]
)

iface.launch()